package com.yunmaozj.tools.lock.interceptor;

import com.yunmaozj.tools.lock.RedisLock;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.env.StandardEnvironment;

import java.io.Serializable;

import static java.util.Objects.isNull;

/**
 * @author 钟明宏
 * @version V1.0
 * @date 2021-08-29 21:33
 **/
public class DistributedLockInterceptor extends AbstractDistributedLockAspectSupport implements MethodInterceptor, Serializable {

    private BeanFactory beanFactory;

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
        return invokeWithinSync(invocation.getMethod(), targetClass, invocation.getArguments(), invocation::proceed);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    @Override
    public void afterPropertiesSet() {
        if (this.beanFactory == null) {
            throw new IllegalStateException(
                    "make sure to run within a BeanFactory " +
                            "containing a TransactionManager bean!");
        }
        if (!lockIsInit()) {
            StandardEnvironment environment = beanFactory.getBean(StandardEnvironment.class);
            String host = environment.getProperty("redis.host", "127.0.0.1");
            int port = environment.getProperty("redis.port", int.class, 6379);
            RedisLock redisLock = new RedisLock(host, port, RedisLock.LockType.DEFAULT);
            redisLock.afterProperties();
            setRedisLock(redisLock);
        }
    }
}
